﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CompositionPlugin.Service
{
    public class UIComposition : IUIComposition
    {
        public virtual void Initialize() { }

        public void ComposeValueInUIContext<T>(Action<T> postAction)
        {
            this.ComposeValueInUIContext<T>(null, postAction);
        }

        public void ComposeValueInUIContext<T>(string name, Action<T> postAction)
        {
            var dispatcher = SystemRuntime.Current.GetService<IUIDispatcher>();
            if (dispatcher == null)
                throw new InvalidOperationException("Cannot find runtime service UIDispather");

            dispatcher.InvokeAsync(new Func<string, Action<T>, T>(this.Resolve<T>), name, postAction);
        }

        public T GetExportedValueInUIContext<T>(Action<T> postAction)
        {
            return this.GetExportedValueInUIContext<T>(null, postAction);
        }

        public T GetExportedValueInUIContext<T>(string name, Action<T> postAction)
        {
            var dispatcher = SystemRuntime.Current.GetService<IUIDispatcher>();
            if (dispatcher == null)
                throw new InvalidOperationException("Cannot find runtime service UIDispather");

            var delg = new Func<string, Action<T>, T>(this.Resolve<T>);

            var result = dispatcher.BeginInvoke<string, Action<T>, T>(delg, null, null, name, postAction);
            return dispatcher.EndInvoke<string, Action<T>, T>(delg, result);
        }

        public virtual void OnRuntimeDisposing() { }

        #region private

        private T Resolve<T>(string name, Action<T> postAction)
        {
            var r = SystemRuntime.Current.Composition.Container.GetExportedValue<T>(name);
            if (postAction != null)
                postAction(r);
            return r;
        }

        #endregion
    }
}
